/********************************************************************************
 * DESCRIPTION OF THE FILE HERE
 ********************************************************************************/

#include "common.h"
#include "system_primitives.h"
#include "mtserver.h"
#include "client.h"
#include "request.h"
#include "response.h"

#include <semaphore.h>

static void printUsage() {
        printf("uso: ./mtserver n [-h]\n");
	printf("\tn -> numero di client da attivare (!= 0) \n");
	exit(0);
}

int main(int argc, char* argv[]) {
  int i;
  int nClients = 0; /* numero di client richiesti  */
  bool inputError = false;
  pid_t server_process;
  pid_t * clients;

  system_init();

  if (argc == 1) {
      inputError = true;
  } else if (argc == 2) {
    if (streq(argv[1],"-h")){
      printUsage();
    } else {
      nClients = atoi(argv[1]);
      if (nClients <= 0) inputError = true;
      }
  } else {
    inputError = true;
  }

  if (inputError) {
    printf("Errore input non valido: ");
    printUsage();
  }

  debug("GOING TO FORK\n");
  server_process = fork();
  if (server_process < 0) throw_error("main", "error in fork");
  if (server_process == 0){
    debug("I ENTERED THE SERVER\n");
    ptrMTServer server = MTServer_create();
    MTServer_listen(server);
    MTServer_destroy(server);
    debug("I EXITED THE SERVER\n");
    return 0;    
  }

  sleep(3);
  debug("I WAITED 3 SECs TO LET THE SERVER START!\n");

  clients = new_vector(pid_t, nClients);
  for (i = 0; i < nClients; i++){
    clients[i] = fork();
    if (clients[i] < 0) throw_error("main", "error in fork");
    if (clients[i] == 0){
      ptrRequest request = Request_create(i);
      ptrClient client = Client_create(request);
      ptrResponse response = Client_sendRequest(client);
      printf("Ecco il risultato ottenuto dal thread %d:\n\t", i);
      Response_printf(response);
      Response_destroy(response);
      Client_destroy(client);
      Request_destroy(request);
      return 0;
    }
  }
  debug("EXITING MAIN\n");

  system_exit();
  return 0;
}
